package com.hymall.controller.admin;

import com.hymall.anno.AddLog;
import com.hymall.bean.*;
import com.hymall.bean.common.BaseRespVo;
import com.hymall.realm.MarketToken;
import com.hymall.service.admin.AdminService;
import com.hymall.service.admin.PermissionsService;
import com.hymall.util.Md5Util;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author: 叶熠彬
 * @description: 整合shiro后的Auth
 * @date: 2022/7/18 20:48
 */
@RestController
@RequestMapping("admin/auth")
public class AuthController {

    @Autowired
    AdminService adminService;
    @Autowired
    PermissionsService permissionsService;


    /**
     * Shiro
     * 如果参数比较少，类型比较简单的话，使用map来接收也可以
     */

    /**
     * 整合shiro后的登录
     *
     * @author: 叶熠彬
     * @date: 2022/7/18 23:27
     * @param: [map]
     * @return: com.hymall.bean.common.BaseRespVo<com.hymall.bean.LoginUserData>
     */
    @AddLog(action = "登录", type = 1)
    @PostMapping("login")
    public BaseRespVo<LoginUserData> login(@RequestBody Map map) {
        String username = (String) map.get("username");
        String password = (String) map.get("password");
        Subject subject = SecurityUtils.getSubject();
        MarketToken token = new MarketToken(username, Md5Util.getMd5(password), "admin");
        //执行Subject提供的login方法
        //token是登录主体Subject执行认证过程中传入系统的参数，其实就是大家绝大部分场景下构造的username和password
        subject.login(token);
        if (subject.isAuthenticated()) {
            //认证成功，根据admin查询相关返回信息
            MarketAdmin marketAdmin = (MarketAdmin) subject.getPrincipals().getPrimaryPrincipal();
            LoginUserData loginUserData = new LoginUserData();
            AdminInfoBean adminInfo = new AdminInfoBean();
            //没必要查
            MarketAdmin admin = adminService.queryAdminByUsername(marketAdmin.getUsername());
            adminInfo.setAvatar(admin.getAvatar());
            adminInfo.setNickName(admin.getUsername());
            loginUserData.setAdminInfo(adminInfo);

            //token：携带SessionId信息
            loginUserData.setToken((String) subject.getSession().getId());
            return BaseRespVo.ok(loginUserData);
        }
        return BaseRespVo.error(400, "登录失败，请重试");
    }

    /**
     * 整合shiro后的info
     *
     * @author: 叶熠彬
     * @date: 2022/7/18 23:27
     * @param: [token]
     * @return: com.hymall.bean.common.BaseRespVo
     */

    @RequestMapping("info")
    public BaseRespVo info(String token) {
        Subject subject = SecurityUtils.getSubject();
        PrincipalCollection principals = null;
        try {
            principals = subject.getPrincipals();
        } catch (Exception e) {
            return BaseRespVo.error(501, "请登录");
        }
        InfoData infoData = new InfoData();
        // 拥有授权
        if (principals != null) {
            if (!principals.isEmpty()) {
                MarketAdmin admin = (MarketAdmin) principals.getPrimaryPrincipal();
                infoData.setName(admin.getUsername());
                infoData.setAvatar(admin.getAvatar());
                //int[]转String列表
                Integer[] ids = admin.getRoleIds();
                List<String> roleIds = new ArrayList<>();
                for (int id : ids) {
                    roleIds.add(String.valueOf(id));
                }
                infoData.setRoles(roleIds);
                List<String> perms = permissionsService.queryPermissionListByRoleIds(ids);

                infoData.setPerms(perms);


                return BaseRespVo.ok(infoData);

            }
        }
        return BaseRespVo.ok(infoData);
    }


    /**
     * 退出登录
     *
     * @author: 叶熠彬
     * @date: 2022/7/18 23:37
     * @param: []
     * @return: com.hymall.bean.common.BaseRespVo
     */
    @AddLog(action = "登出", type = 1)
    @PostMapping("logout")
    public BaseRespVo logout() {
        Subject subject = SecurityUtils.getSubject();
        MarketAdmin primaryPrincipal = (MarketAdmin) subject.getPrincipals().getPrimaryPrincipal();
        subject.logout();
        //用error方法携带一些登出的用户信息
        return BaseRespVo.error(0, primaryPrincipal.getUsername());
    }

    /**
     * 拒绝访问
     *
     * @author: 叶熠彬
     * @date: 2022/7/18 23:39
     * @param: []
     * @return: com.hymall.bean.common.BaseRespVo
     */
    @RequestMapping("noAuthc")
    public BaseRespVo noAuthc() {
        return BaseRespVo.error(501, "请重新登录");
    }

}
